package com.cby.android.library.base

import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import com.cby.android.library.R
import com.cby.android.library.base.callback.*
import com.cby.android.library.ext.observe
import com.cby.android.library.mvi.*
import com.cby.android.olive.utils.NetworkUtils
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import java.lang.reflect.ParameterizedType

abstract class BaseStateFragment<VM : BaseStateViewModel<S, I>, S: IState, I: IIntent> : BaseLazyFragment() {


    var loadService: LoadService<Any>? = null

    var viewModel: VM? = null

    override fun onDataInit() {
        initViewModel()
        pageStatusPopulate()
    }

    private fun initViewModel() {
        viewModel = obtainViewModel()
        bindLiveData()
    }

    abstract fun bindLiveData()


    private fun pageStatusPopulate() {
        if(needPageStatus()) {
            initLoadSir()
            observePageStatus()
        }
    }

    /**
     * 初始化页面状态服务对象
     */
    open fun initLoadSir() {
        loadService = LoadSir.getDefault().register(getPageTarget()) {
            reload()
        }

    }

    /**
     * 监听页面状态
     */
    open fun observePageStatus() {
        observe(viewModel!!.pageStatus) {
            when(it){
                PageStatus.Loading -> pageLoading()
                PageStatus.Success -> loadService?.showSuccess()
                PageStatus.Empty -> loadService?.showCallback(EmptyCallback::class.java)
                is PageStatus.Error -> {
                    loadService?.setCallBack(ErrorCallback::class.java) {
                            _, view ->
                        run {
                            val errorTv = view.findViewById<TextView>(R.id.tv_error)
                            it.error.message?.let { it1 -> errorTv.text = it1 }
                        }
                    }
                    pageError(it.error)

                }
            }
        }
    }

    /**
     * 页面加载状态的处理方法
     */
    open fun pageLoading() {
        loadService?.showCallback(LottieLoadingCallback::class.java)
    }

    open fun pageError(error: ApiError) {
        loadService?.showCallback(if(NetworkUtils.isConnected(requireActivity())) {
            ErrorCallback::class.java
        } else {
            TimeoutCallback::class.java
        })
    }

    /**
     * 是否需要页面状态功能，默认为true
     */
    open fun needPageStatus() = true

    /**
     * 页面加载状态绑定的目标对象
     */
    open fun getPageTarget() : Any?{
        return rootView
    }

    /**
     * 加载异常，重新加载的方法抽象
     */
    abstract fun reload()


    open fun <VM> getGenericType(`object`: Any, index: Int): Class<VM> {
        return (`object`
            .javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[index] as Class<VM>
    }



    protected open fun obtainViewModel(): VM? {
        return try {
            val modelClass: Class<VM> = getGenericType(this, 0)
            ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().application).create(
                modelClass)
        } catch (e: ClassCastException) {
            null
        }
    }

}